//#########################################################################
//                              WackiEngie
//           Copyright (c) 2014 Marc Wacker. All rights reserved.
//#########################################################################

#pragma once

#include "WeUtilPrerequisites.h"

namespace WackiEngine
{
	template<class T>
	class Vector2 {
	public:
		T	x, y;

		Vector2(const T x_ = 0, const T y_ = 0) { x = x_; y = y_; }
		Vector2(const Vector2& v) { x = v.x; y = v.y; }

		void		set(T x_, T y_) { x = x_; y = y_; }
		void		set(const Vector2& v) { x = v.x; y = v.y; }

		//compare operators
		bool		operator==	(const Vector2& b) const	{ return x == b.x && y == b.y; }
		bool		operator!=	(const Vector2& b) const	{ return x != b.x || y != b.y; }

		//operators with temp allocation
		Vector2	operator-	(void) const				{ return Vector2(-x, -y); }
		Vector2	operator+	(const Vector2& v) const	{ return Vector2(x + v.x, y + v.y); }
		Vector2	operator-	(const Vector2& v) const	{ return Vector2(x - v.x, y - v.y); }
		T		operator*	(const Vector2& v) const	{ return x*v.x + y*v.y; };  // dot

		Vector2	operator*	(const T s) const			{ return Vector2(x*s, y*s); }
		Vector2	operator/	(const T s) const			{ return Vector2(x / s, y / s); }
		Vector2	operator&	(const Vector2& v) const	{ return Vector2(x*v.x, y*v.y); }

		friend Vector2   operator *  (T s, const Vector2& v)  { return Vector2(v.x*s, v.y*s); }

		//assign operators
		Vector2&	operator=	(const Vector2& v)	{ x = v.x; y = v.y;		return *this; }
		Vector2&	operator+=	(const Vector2& v)	{ x += v.x; y += v.y;	return *this; }
		Vector2&	operator-=	(const Vector2& v)	{ x -= v.x; y -= v.y;	return *this; }
		Vector2&	operator+=	(const T s)			{ x += s; y += s;		return *this; }
		Vector2&	operator-=	(const T s)			{ x -= s; y -= s;		return *this; }
		Vector2&	operator*=	(const T s)			{ x *= s; y *= s;		return *this; }
		Vector2&	operator/=	(const T s)			{ x /= s; y /= s;		return *this; }
		Vector2&	operator&=	(const Vector2& v)	{ x *= v.x; y *= v.y;	return *this; }

		T			dot(const Vector2 &v)			{ return x * v.x + y * v.y; }
		T			lengthSq()						{ return x * x + y * y; }
		T			length()						{ return sqrt(lengthSq()); }
		void		normalize()						{ T l = length(); if(l>0) *this /= l; }
		Vector2		normalized()					{ T l = length(); if(l > 0) return *this / l; else return *this; }
	};

	typedef Vector2<float> Vector2f;
	typedef Vector2<int32> Vector2i;

}